package com.changgou.utils;

/**
 * author：wuBin
 * 类的描述：来封装文件的一些操作的方法
 * 文件的上传，下载，删除，获取文件的内容
 */

import com.changgou.file.FastDFSFile;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.springframework.core.io.ClassPathResource;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 完整的文件的处理的操作步骤，是严格的遵循着操作步骤的
 * 首先要先读取Tracker的相关的配置信息。获取到端口号和ip地道道它的Connection
 */
public class FileFastDFSUtil {

    //读取配置文件，获取Tracker的配置信息
    static {
        try {
            String path = new ClassPathResource("fdfs_client.conf").getPath();
            ClientGlobal.init(path);//加载tracker的信息
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /***
     * 文件上传信息的封装，由控制层中获取到上传文件的信息，将信息
     * 封装到FastDFSFile这个对象中
     */
    public static String[] uploadFile(FastDFSFile fastDFSFile) throws Exception {

        //调用封装方法获取TrackerServer
        TrackerServer trackerServer = getTrackerServer();

        //调用封装方法获取StorageClient
        StorageClient storageClient = getStorageClient(trackerServer);

        /**
         * 参数1：上传文件的字节数组
         * 参数2：上传文件的扩展名
         * 参数3：上传文件的补充信息。
         */
        NameValuePair[] nameValuePair = new NameValuePair[1];
        nameValuePair[0] = new NameValuePair("拍摄地","盐城");

        /**
         * 注意这个upload方法很有玄妙，里面封装了两个值给我们
         * 1.string[0]:封装的是我们上传文件的组名称group1
         * 2.string[1]:是我们文件上传到stroage中的文件名字   M00/02/04/XXXX.jpg
         */
        String[] strings = storageClient.upload_file(fastDFSFile.getContent(), fastDFSFile.getExt(), nameValuePair);

        return strings;

    }


    /**
     * 获取文件的内容
     * @param groupName 文件所在组的名称  group1
     * @param remoteName  文件上传的名称  M00/00/00/wKjThF0DBzaAP23MAAXz2mMp9oM26.jpeg
     * @return
     */
    public static FileInfo getFile(String groupName, String remoteName) throws Exception {

        //调用封装方法获取TrackerServer
        TrackerServer trackerServer = getTrackerServer();

        //调用封装方法获取StorageClient
        StorageClient storageClient = getStorageClient(trackerServer);

        FileInfo file_info = storageClient.get_file_info(groupName, remoteName);

        return  file_info;  //经文件的信息封装到这个file_info中

    }


    /**
     * 文件的下载
     * @param groupName 文件所在组的名称  group1
     * @param remoteName 文件上传的名称  M00/00/00/wKjThF0DBzaAP23MAAXz2mMp9oM26.jpeg
     * @return
     */
    public static InputStream downloadFile(String groupName, String remoteName) throws Exception {
        //调用封装方法获取TrackerServer
        TrackerServer trackerServer = getTrackerServer();

        //调用封装方法获取StorageClient
        StorageClient storageClient = getStorageClient(trackerServer);


        //获取到的是一个字节的数组
        byte[] bytes = storageClient.download_file(groupName, remoteName);

        //为了测试方便，我们通常是将文件的字节数组转成InputStream对象

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);

        return byteArrayInputStream;

    }


    /**
     * 删除文件
     * @param groupName  文件所在组的名称  group1
     * @param remoteName 文件上传的名称  M00/00/00/wKjThF0DBzaAP23MAAXz2mMp9oM26.jpeg
     */
    public static void deleteFile(String groupName, String remoteName) throws Exception {
        //调用封装方法获取TrackerServer
        TrackerServer trackerServer = getTrackerServer();

        //调用封装方法获取StorageClient
        StorageClient storageClient = getStorageClient(trackerServer);


        storageClient.delete_file(groupName, remoteName);

    }


    /**
     * 获取Storage服务的IP、端口信息
     * @return
     */
    public static StorageServer getStorageInfo(String groupName, String remoteName) throws Exception {
        TrackerClient trackerClient = new TrackerClient();

        TrackerServer trackerServer = trackerClient.getConnection();

        StorageServer storage = trackerClient.getFetchStorage(trackerServer, groupName, remoteName);

        return storage; //Storage的相关信息都封装在这个里面

    }


    /**
     * 获取Tracker服务地址
     * @return
     */
    public static String getTrackerServerUrl() throws Exception {
        //调用封装方法获取TrackerServer
        TrackerServer trackerServer = getTrackerServer();

        String hostString = trackerServer.getInetSocketAddress().getHostString(); //获取的ip地址

        int port = ClientGlobal.getG_tracker_http_port(); //我们在配置文件中配置的端口号的信息

        return "http://"+hostString+":"+port;  //拼接好端口号

    }


    public static void main(String[] args) throws Exception {

        /*******1.测试获取文件内容*********/
//        FileInfo fileInfo = getFile("group1", "M00/00/00/wKhQiF73WUmAQc0QAA6JoT0fN2o169.jpg");
//
//        System.out.println(fileInfo.getSourceIpAddr());
//
//        System.out.println(fileInfo.getFileSize());


        /**************2.测试文件的下载*************/
//        InputStream in = downloadFile("group1", "M00/00/00/wKhQiF73WUmAQc0QAA6JoT0fN2o169.jpg");
//
//        FileOutputStream out = new FileOutputStream("D:/imagess/1.jpg"); //将图片下载到这个位置
//
//        byte[] bytes = new byte[1024];//从这个字节缓冲区中去读取
//        while (in.read(bytes)!=-1){
//            //不为-1证明存在数据
//            out.write(bytes);
//        }
//
//        out.flush();//刷新缓冲区
//        out.close();
//        in.close();


        /************测试文件的删除*************/

//        deleteFile("group1", "M00/00/00/wKhQiF73WQaASXEWAA6JoT0fN2o000.jpg");



        /*****************测试Tracker服务地址******************/

        System.out.println(getTrackerServerUrl());
    }



    /*******代码优化下******/
//    获取TrackerServer
    public static TrackerServer getTrackerServer() throws Exception {
        //1.创建访问trancker-server的客户端
        TrackerClient trackerClient = new TrackerClient();
        //2.通过trackerClient访问trackerServer服务，获取连接对象信息
        TrackerServer trackerServer = trackerClient.getConnection();

        return  trackerServer;

    }


    //获取StorageClient
    public static StorageClient getStorageClient(TrackerServer trackerServer){

        StorageClient storageClient = new StorageClient(trackerServer,null);
        return storageClient;
    }
}
